<script setup lang="ts">
import { isClient } from '@opensig/opendesign';
import { nextTick, ref, watch } from 'vue';
import { useRoute } from 'vitepress/client';
import { useScreen } from '@/composables/useScreen.ts';
import OAnchor from '@/components/anchor/OAnchor.vue';
import OAnchorItem from '@/components/anchor/OAnchorItem.vue';

interface AnchorDataT {
  id: string;
  href: string | null;
  tagName: string;
  children?: AnchorDataT[];
}

const anchorData = ref<AnchorDataT[]>([]);
const route = useRoute();

withDefaults(
  defineProps<{
    selector: string;
  }>(),
  {
    selector: '#app > .o-scroller > .o-scroller-container',
  }
);

const emits = defineEmits(['get-anchor-data', 'anchor-changed']);

const getAnchorItem = (ele: HTMLElement) => {
  return {
    id: ele.innerText.replace(/[\u200B-\u200D\uFEFF]/g, ''),
    href: ele.children[0].getAttribute('href') || `#${ele.id}`,
    tagName: ele.tagName,
  };
};

const getAnchorData = () => {
  anchorData.value = [];
  if (isClient) {
    const docMain = document.querySelector('.docs-content');
    if (docMain) {
      const elements = Array.from(docMain.querySelectorAll('h1, h2'));
      let index = 1;
      for (let i = 0; i < elements.length; i++) {
        if (elements[i].tagName === 'H1') {
          index = 1;
          anchorData.value.push(getAnchorItem(elements[i] as HTMLElement));
        } else {
          const last = anchorData.value[anchorData.value.length - 1];
          if (last && last.tagName === 'H1') {
            if (index === 1) {
              last.children = [];
              index++;
            }
            last.children?.push(getAnchorItem(elements[i] as HTMLElement));
          } else {
            anchorData.value.push(getAnchorItem(elements[i] as HTMLElement));
          }
        }
      }
    }
  }
  emits('get-anchor-data', anchorData.value);
};

watch(
  () => route.path,
  () => {
    anchorData.value = [];
    nextTick(() => {
      getAnchorData();
    });
  },
  { immediate: true }
);

const anchorChanged = (e) => {
  emits('anchor-changed', e);
};

const { isPhone } = useScreen();
</script>

<template>
  <div class="doc-anchor-content">
    <OAnchor v-if="anchorData.length" :targetOffset="80 + (isPhone ? 48 : 0)" :container="selector" @change="anchorChanged">
      <div v-for="item in anchorData" :key="item.id" :title="item.id">
        <OAnchorItem
          v-analytics.addUrl="{ service: 'docs', properties: { target: item.id, type: 'anchor' } }"
          :title="item.id"
          :href="item.href"
          :key="item.id"
        >
          <div v-for="subItem in item.children" :key="subItem.id" :title="subItem.id">
            <OAnchorItem
              v-analytics.addUrl.stop="{ service: 'docs', properties: { target: subItem.id, type: 'anchor' } }"
              :href="subItem.href"
              :title="subItem.id"
              :key="subItem.id"
            />
          </div>
        </OAnchorItem>
      </div>
    </OAnchor>
  </div>
</template>

<style scoped lang="scss">
.doc-anchor-content {
  :deep(.o-anchor) {
    display: flex;

    .o-anchor-items {
      flex-grow: 1;
    }

    .o-anchor-item-link {
      display: block;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;

      &:hover {
        &:not(.is-active) {
          color: var(--o-color-ubmc-hover);
        }
      }
    }

    .o-anchor-indicator {
      &::after {
        height: 100%;
      }
    }
  }
}
</style>
